import pymysql


class DB():

    def __init__(self, host='localhost', port=3306, db='', user='root', passwd='root', charset='utf8'):
        print("init执行")
        # 建立连接
        self.conn = pymysql.connect(host=host, port=port, db=db, user=user, passwd=passwd, charset=charset)
        # 创建游标，操作设置为字典类型
        self.cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

    def __enter__(self):
        print("enter执行")
        # 返回游标
        return self.cur

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exit执行")
        # 提交数据库并执行
        self.conn.commit()
        # 关闭游标
        self.cur.close()
        # 关闭数据库连接
        self.conn.close()


# 我们前面文章介绍了迭代器和可迭代对象，这次介绍python的上下文管理。在python中实现了__enter__和__exit__方法，即支持上下文管理器
# 协议。上下文管理器就是支持上下文管理器协议的对象，它是为了with而生。当with语句在开始运行时，会在上下文管理器对象上调用
# __enter__ 方法。with语句运行结束后，会在上下文管理器对象上调用 __exit__ 方法


# 模块是对象，并且所有的模块都有一个内置属性 __name__。一个模块的 __name__ 的值取决于您如何应用模块。如果 import 一个模块，
# 那么模块__name__ 的值通常为模块文件名，不带路径或者文件扩展名。但是您也可以像一个标准的程序样直接运行模块，在这 种情况下,
# __name__ 的值将是一个特别缺省"__main__"。
# 在cmd 中直接运行.py文件,则__name__的值是'__main__';
# 而在import 一个.py文件后,__name__的值就不是'__main__'了;
# 从而用if __name__ == '__main__'来判断是否是在直接运行该.py文件
print(__name__)
if __name__ == '__main__':
    with DB(host='127.0.0.1', user='root', passwd='root', db='mydb') as db:
        db.execute('select * from demo')
        print(db)
        for i in db:
            print(i)
